﻿namespace ReflectionStudio.LocalizationLibrary
{
    //.NET References
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Represents a collection of <see cref="DynamicResourceToken"/>s.
    /// </summary>
    internal class DynamicResourceTokenQueue
    {
        //Fields

        private Dictionary<Language, LinkedList<DynamicResourceToken>> _queuesDictionary;

        //Properties

        /// <summary>
        /// Gets\Sets the current language.
        /// </summary>
        public Language CurrentLanguage { get; set; }

        /// <summary>
        /// Gets the number of elements contained in the <see cref="DynamicResourceTokenQueue."/>.
        /// </summary>
        public int Count 
        {
            get 
            {
                int count = 0;
                foreach (var queueItem in this.QueuesDictionary)
                {
                    count += queueItem.Value.Count;
                }
                return count;
            }
        }

        ///// <summary>
        ///// Gets the number of elements contained in the <see cref="DynamicResourceTokenQueue."/> for current language.
        ///// </summary>
        //public int CountForCurrentLanguage
        //{
        //    get
        //    {
        //        int count = 0;
        //        if ((this.CurrentLanguage != null) && (this.QueuesDictionary.ContainsKey(this.CurrentLanguage)))
        //        {
        //            count = this.QueuesDictionary[this.CurrentLanguage].Count;
        //        }
        //        return count;
        //    }
        //}

        /// <summary>
        /// Dictionary of <see cref="DynamicResourceToken"/>'s queues.
        /// </summary>
        protected Dictionary<Language, LinkedList<DynamicResourceToken>> QueuesDictionary 
        {
            get 
            {
                if (this._queuesDictionary == null)
                {
                    this._queuesDictionary = new Dictionary<Language, LinkedList<DynamicResourceToken>>();
                }
                return this._queuesDictionary;
            } 
        }

        //Methods

        /// <summary>
        /// Removes and returns the <see cref="DynamicResourceToken"/> at the beginning of the <see cref="DynamicResourceTokenQueue"/>
        /// </summary>
        /// <returns>First DynamicResource from the queue.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown whether Count is euquals to 0.
        /// </exception>
        public DynamicResourceToken Dequeue() 
        {
            if (this.Count == 0)
            {
                throw new InvalidOperationException("Queue is empty.");
            }
            DynamicResourceToken token = null;
            if ((this.QueuesDictionary.ContainsKey(this.CurrentLanguage)) &&
                (this.QueuesDictionary[this.CurrentLanguage].Count > 0))
            {
                token = this.QueuesDictionary[this.CurrentLanguage].First.Value;
                this.QueuesDictionary[this.CurrentLanguage].RemoveFirst();
            }
            else
            {
                foreach (var queueItem in this.QueuesDictionary)
                {
                    if (queueItem.Value.Count > 0)
                    {
                        token = queueItem.Value.First.Value;
                        queueItem.Value.RemoveFirst();
                        break;
                    }
                }
            }
            return token;
        }

        /// <summary>
        /// Adds an object to the end of the <see cref="DynamicResourceTokenQueue"/>.
        /// </summary>
        /// <param name="token">Token to add.</param>
        public bool Enqueue(DynamicResourceToken token) 
        {
            bool retVal = false;
            if (token != null)
            {
                if (!this.QueuesDictionary.ContainsKey(token.Language))
                {
                    LinkedList<DynamicResourceToken> linkedList = new LinkedList<DynamicResourceToken>();
                    linkedList.AddLast(token);
                    this.QueuesDictionary.Add(token.Language, linkedList);
                    retVal = true;
                }
                else if (!this.QueuesDictionary[token.Language].Contains(token))
                {
                    this.QueuesDictionary[token.Language].AddLast(token);
                    retVal = true;
                }
            }
            return retVal;
        }

        /// <summary>
        /// Remove the input token from the queue.
        /// </summary>
        /// <param name="token">Token to remove.</param>
        public void Remove(DynamicResourceToken token) 
        {
            if ((token != null) && this.QueuesDictionary.ContainsKey(token.Language))
            {
                LinkedList<DynamicResourceToken> linkedList = this.QueuesDictionary[token.Language];
                if (linkedList.Contains(token))
                {
                    linkedList.Remove(token);
                }
            }
        }

        /// <summary>
        /// Clears the queue.
        /// </summary>
        public void Clear() 
        {
            this.QueuesDictionary.Clear();
        }
    }
}